package com.cqjtu.store.user.service.impl;

import com.cqjtu.store.common.*;
import com.cqjtu.store.user.mapper.UserMapper;
import com.cqjtu.store.user.pojo.dto.PwdUpdateDTO;
import com.cqjtu.store.user.pojo.dto.UserLoginDTO;
import com.cqjtu.store.user.pojo.dto.UserRegDTO;
import com.cqjtu.store.user.pojo.dto.UserUpdateDTO;
import com.cqjtu.store.user.pojo.entity.User;
import com.cqjtu.store.user.pojo.vo.UserLoginVO;
import com.cqjtu.store.user.pojo.vo.UserVO;
import com.cqjtu.store.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.UUID;

/**
 * @ProjectName: cqjtu-store
 * @Titile: UserServiceImpl
 * @Author: Lucky
 * @Description: 用户业务实现类
 */
@Service
@Transactional(rollbackFor = Exception.class)
@Slf4j
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Override
    public void register(UserRegDTO userRegDTO) {
        // todo 判断 密码和重复密码是否一致
        User existsUser =  userMapper.getUserByName(userRegDTO.getUsername());
        if(existsUser!=null){
            throw new ServiceException(ServiceCode.ERR_EXISTS,"该用户已经存在,不能重复注册.");
        }
        User user = new User();
        user.setUsername(userRegDTO.getUsername());
        String salt = UUID.randomUUID().toString().replace("-","");
        user.setSalt(salt);
        String password = MD5Utils.enctype(userRegDTO.getPassword(),salt,Constants.HASH_TIME);
        user.setPassword(password);
        //是否被删除
        user.setIsDelete(Constants.IS_NOT_DELETE);
        user.setCreatedUser(userRegDTO.getUsername());
        int result = userMapper.insert(user);
        if(result != 1){
            throw new ServiceException(ServiceCode.ERR_SAVE_FAILED,"注册用户失败");
        }

    }

    /**
     * 登录业务逻辑
     * @param userLoginDTO
     * @return
     */
    @Override
    public UserLoginVO login(UserLoginDTO userLoginDTO) {
        // 根据用户名去查询用户
        User user = userMapper.getUserByName(userLoginDTO.getUsername());
        if(user==null){
            //返回的是前端开发人员
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,"用户不存在");
        }
        //对密码进行加密后才判断
        String password = MD5Utils.enctype(userLoginDTO.getPassword(), user.getSalt(), Constants.HASH_TIME);
        if(!password.equals(user.getPassword())){
            throw new ServiceException(ServiceCode.ERR_PWD,"密码错误");
        }
        //从user中取出需要的数据：id,username,封装
        UserLoginVO userLoginVO = new UserLoginVO();
        userLoginVO.setId(user.getId());
        userLoginVO.setUsername(user.getUsername());
        //生成token
        String token = JwtUtils.generateToken(userLoginVO);
        userLoginVO.setToken(token);
        return userLoginVO;
    }

    /**
     * 修改密码的业务
     * @param pwdUpdateDTO
     */
    @Override
    public void updatePwd(PwdUpdateDTO pwdUpdateDTO,UserLoginVO userLoginVO) {
        if (!pwdUpdateDTO.getNewPwd().equals(pwdUpdateDTO.getReNewPwd())){
            throw new ServiceException(ServiceCode.ERR_FORBIDDEN,"新密码和重复密码不一致");
        }
        //判断用户是否存在
        User user = userMapper.getUserByName(userLoginVO.getUsername());
        if(user==null){
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,"用户不存在");
        }
        // 判断密码是否正确
        String oldPassword = MD5Utils.enctype(pwdUpdateDTO.getOldPwd(),user.getSalt(),Constants.HASH_TIME);
        if(!oldPassword.equals(user.getPassword())){
            throw new ServiceException(ServiceCode.ERR_PWD,"密码错误");
        }
        //修改密码
        //获取salt
        String salt = UUID.randomUUID().toString().replace("-","");
        //加密
        String newPassword = MD5Utils.enctype(pwdUpdateDTO.getNewPwd(),salt,Constants.HASH_TIME);
        //构造一个用户对象
        User updateUser = new User();
        updateUser.setId(userLoginVO.getId());
        updateUser.setPassword(newPassword);
        updateUser.setSalt(salt);
        updateUser.setModifiedUser(userLoginVO.getUsername());
        int result =  userMapper.updatePwd(updateUser);
        if(result!=1){
            throw new ServiceException(ServiceCode.ERR_SAVE_FAILED,"修改密码失败");
        }
    }

    /**
     * 查询用户
     * @param userLoginVO
     * @return
     */
    @Override
    public UserVO getUser(UserLoginVO userLoginVO) {
        User user = userMapper.getUserByName(userLoginVO.getUsername());
        if(user==null){
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,"用户不存在");
        }
        //封装查询的用户信息
        UserVO userVO = new UserVO();
        userVO.setUsername(user.getUsername());
        userVO.setPhone(user.getPhone());
        userVO.setEmail(user.getEmail());
        userVO.setGender(user.getGender());
        return userVO;
    }

    /**
     * 修改用户信息
     * @param userUpdateDTO 修改的信息
     * @param userLoginVO 修改人
     */
    @Override
    public void updateUser(UserUpdateDTO userUpdateDTO, UserLoginVO userLoginVO) {
        if(!userUpdateDTO.getUsername().equals(userLoginVO.getUsername())){
            throw new ServiceException(ServiceCode.ERR_FORBIDDEN,"该用户禁止修改");
        }
        User user = new User();

        user.setUsername(userLoginVO.getUsername());
        user.setPhone(userUpdateDTO.getPhone());
        user.setEmail(userUpdateDTO.getEmail());
        user.setGender(userUpdateDTO.getGender());
        user.setModifiedUser(userLoginVO.getUsername());
        int result = userMapper.updateUser(user);
        if(result!=1){
            throw new ServiceException(ServiceCode.ERR_SAVE_FAILED,"用户修改失败");
        }

    }

    /**
     * 上传头像
     * @param avatar 头像
     * @param userLoginVO 上传头像的那个人
     */
    @Override
    public void upload(MultipartFile avatar, UserLoginVO userLoginVO) {
        //明确图片保存在哪里？？？(看笔记，视频)
        //为了演示案例的方便，我们把图片保存在源码中: /resources/static/images
        String savePath = System.getProperty("user.dir")+ File.separator+
                "store-project"+File.separator+
                "src"+File.separator+
                "main"+File.separator+
                "resources"+File.separator+
                "static"+File.separator+
                "images";
        log.debug("保存的路径:{}",savePath);
        //获取文件的名称（全名称，包括后缀）
        String filename = avatar.getOriginalFilename();
        //String type = avatar.getContentType(); // mime类型
        // todo 判断文件的类型是否符合要求
        //todo 判断文件的大小是否符合要求
        //生成一个随机的名称+拼接后缀
        // abc.png =>随机名称.png
        filename = UUID.randomUUID().toString().replace("-","")+
                filename.substring(filename.lastIndexOf("."));
        log.debug("文件的新名：{}",filename);
        //上传
        File saveFile = new File(savePath, filename);
        try {
            avatar.transferTo(saveFile);
        } catch (IOException e) {
            throw new ServiceException(ServiceCode.ERR_SAVE_FAILED,"文件上传失败");
        }
        //将头像的路径持久化到数据库去
        User user = new User();
        user.setUsername(userLoginVO.getUsername());
        user.setAvatar(filename);
        user.setModifiedUser(userLoginVO.getUsername());
        int result =  userMapper.saveAvatar(user);
        if(result != 1){ //为了模拟数据事务回滚
            //删除文件
            if(saveFile.exists()){
                saveFile.delete();
            }
            throw new ServiceException(ServiceCode.ERR_SAVE_FAILED,"头像路径保存数据库失败");
        }

    }
}
